from django.shortcuts import render
from django.views import View
from django import http
from django.core.paginator import Paginator
from django.utils import timezone


from .models import GoodsCategory,SKU,GoodsVisitCount
from meiduo_mall.utils.response_code import RETCODE
from .utils import get_breadcrumb
from contents.utils import get_categories
# Create your views here.


# /list/(?P<category_id>\d+)/(?P<page_num>\d+)/?sort=排序方式
class ListView(View):
    """商品列表页"""

    def get(self, request, category_id, page_num):
        """提供商品列表页面"""

        # 判断商品类别是否存在
        try:
            category = GoodsCategory.objects.get(id = category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseNotFound('商品类别不存在')
        # 提取sort排序参数
        sort = request.GET.get('sort', 'default')
        if sort == 'price':
            # 按价格由低到高
            sort_field = 'price'
        elif sort == 'hot':
            # 按销量由高到底
            sort_field = '-sales'
        else:
            # sort = 'default',按创建时间新到老
            sort_field = '-create_time'

        # 查询当前三级分类下所有sku
        sku_qs = category.sku_set.filter(is_launched=True).order_by(sort_field)
        # 使用django的分页器分页
        paginator = Paginator(sku_qs, 5) # 创建分页对象（分页数据,每页多少数据）
        page_skus = paginator.page(page_num) # 指定分页面的数据
        total_page = paginator.num_pages # 总页数
        categories = get_categories()
        breadcrumb = get_breadcrumb(category)

        context = {
            'categories': categories,  # 频道分类
            'breadcrumb': breadcrumb,  # 面包屑导航
            'sort': sort,  # 排序字段
            'category': category,  # 第三级分类
            'page_skus': page_skus,  # 分页后数据
            'total_page': total_page,  # 总页数
            'page_num': page_num,  # 当前页码
        }
        return render(request, 'list.html', context)


class HotGoodsView(View):
    """热销排行数据"""
    def get(self, request, category_id):
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseNotFound('商品类别不存在')
        # 按销量排行取前两个
        sku_qs = category.sku_set.filter(is_launched=1).order_by('-sales')[0:2]
        hot_skus = []
        for sku in sku_qs:
            hot_skus.append(
                {'id': sku.id, 'name': sku.name, 'price': sku.price, 'default_image_url': sku.default_image.url}
            )
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus': hot_skus})


class DetailView(View):
    """商品详情页"""
    def get(self, request, sku_id):
        """提供商品详情页"""
        try:
            sku = SKU.objects.get(id=sku_id)
        except GoodsCategory.DoesNotExist:
            return render(request, '404.html')
        # category = GoodsCategory.objects.get(id = category_id)
        # category = GoodsCategory.objects.get(sku__id=sku_id)

        category = sku.category     # 获取当前sku所对应的三级分类

        # 1.获取当前sku显示的规格选项ID列表

        spu = sku.spu
        current_sku_spec_qs = sku.specs.all().order_by('spec_id')
        current_sku_option_ids = []     # [8,11]    选项ID列表

        for temp_spec in current_sku_spec_qs:
            current_sku_option_ids.append(temp_spec.option_id)

        # 获取当前spu下所有sku对应的规格选项的映射关系
        """2.构造规格选择仓库
        {(8, 11): 3, (8, 12): 4, (9, 11): 5, (9, 12): 6, (10, 11): 7, (10, 12): 8}
        """
        # 构造规格选择仓库
        temp_sku_qs = spu.sku_set.all()     # spu下所有sku查询集

        spec_sku_map = {}

        for temp_sku in temp_sku_qs:    # 遍历每个sku，获取每个sku显示的规格选项ID列表

            temp_sku_spec_qs = temp_sku.specs.all().order_by('spec_id')
            temp_sku_option_ids = []  # [8,11]    选项ID列表

            for temp_spec in temp_sku_spec_qs:
                temp_sku_option_ids.append(temp_spec.option_id)
            spec_sku_map[tuple(temp_sku_option_ids)] = temp_sku.id

        """3.组合 并找到sku_id 绑定"""
        spu_spec_qs = spu.specs.order_by('id')  # 获取当前spu中的所有规格

        for index, spec in enumerate(spu_spec_qs):  # 遍历当前所有的规格
            spec_option_qs = spec.options.all()  # 获取当前规格中的所有选项
            temp_option_ids = current_sku_option_ids[:]  # 复制一个新的当前显示商品的规格选项列表
            for option in spec_option_qs:  # 遍历当前规格下的所有选项
                temp_option_ids[index] = option.id  # [8, 12]
                option.sku_id = spec_sku_map.get(tuple(temp_option_ids))  # 给每个选项对象绑定下他sku_id属性

            spec.spec_options = spec_option_qs  # 把规格下的所有选项绑定到规格对象的spec_options属性上

        # 渲染页面
        context = {
            'categories': get_categories(),  # 商品分类
            'breadcrumb': get_breadcrumb(category),  # 面包屑导航
            'sku': sku,  # 当前要显示的sku模型对象
            'category': category,  # 当前的显示sku所属的三级类别
            'spu': spu,  # sku所属的spu
            'spec_qs': spu_spec_qs,  # 当前商品的所有规格数据
        }
        return render(request, 'detail.html', context)


class DetailVisitView(View):
    """商品类别每日访问量统计"""
    def post(self, request, category_id):
        # 校验category_id是否存在
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.Http404('商品不存在')

        # 获取当前日期
        today_date = timezone.localdate()
        # 查询当前类别今天有没有统计过
        try:
            count_data = GoodsVisitCount.objects.get(category=category, date=today_date)
        except GoodsVisitCount.DoesNotExist:
            # 如果不存在
            count_data = GoodsVisitCount(
                category=category,
            )

        count_data.count += 1
        count_data.save()
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok'})







